class Solution:
def calculateMinimumHP(self, dungeon: List[List[int]]) -> int:
m, n = len(dungeon), len(dungeon[0])
memo = [[[None] * 2 for _ in range(n)] for _ in range(m)]
def check(h, i, j):
if memo[i][j][0] and h >= memo[i][j][0]:
return True
if memo[i][j][1] and h <= memo[i][j][1]:
return False
if h <= 0:
return False
result = None
if i == m-1 and j == n-1:
result = h + dungeon[i][j] > 0
elif i == m-1:
result = check(h + dungeon[i][j], i, j+1)
elif j == n-1:
result = check(h + dungeon[i][j], i+1, j)
else:
result = check(h + dungeon[i][j], i+1, j) or check(h + dungeon[i][j], i, j+1)
if result:
memo[i][j][0] = h
return True
else:
memo[i][j][1] = h
return False
low, high = 0, 2**31
while low < high:
mid = low + (high-low)//2
if check(mid, 0, 0):
high = mid
else:
low = mid + 1
return low
1373D - Maximum Sum on Even Positions | 1574C - Slay the Dragon |
621A - Wet Shark and Odd and Even | 1395A - Boboniu Likes to Color Balls |
1637C - Andrew and Stones | 1334B - Middle Class |
260C - Balls and Boxes | 1554A - Cherry |
11B - Jumping Jack | 716A - Crazy Computer |
644A - Parliament of Berland | 1657C - Bracket Sequence Deletion |
1657B - XY Sequence | 1009A - Game Shopping |
1657A - Integer Moves | 230B - T-primes |
630A - Again Twenty Five | 1234D - Distinct Characters Queries |
1183A - Nearest Interesting Number | 1009E - Intercity Travelling |
1637B - MEX and Array | 224A - Parallelepiped |
964A - Splits | 1615A - Closing The Gap |
4C - Registration System | 1321A - Contest for Robots |
1451A - Subtract or Divide | 1B - Spreadsheet |
1177A - Digits Sequence (Easy Edition) | 1579A - Casimir's String Solitaire |